/******************************************************************************* * Copyright (c) 2004, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ant.internal.ui.model; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.eclipse.ant.core.AntSecurityException; import org.eclipse.ant.internal.core.IAntCoreConstants; import org.eclipse.ant.internal.ui.AntUIImages; import org.eclipse.ant.internal.ui.IAntUIConstants; import org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor; import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.IRegion; import org.xml.sax.Attributes; public class AntPropertyNode extends AntTaskNode { private String fValue = null; private String fReferencedName; private String fOccurrencesStartingPoint = IAntCoreConstants.VALUE; private String fOccurrencesIdentifier; /* * The set of properties defined by this node name-> value mapping */ private Map<String, String> fProperties = null; public AntPropertyNode(Task task, Attributes attributes) { super(task); String label = attributes.getValue(IAntCoreConstants.NAME); if (label == null) { label = attributes.getValue(IAntCoreConstants.FILE); if (label != null) { fReferencedName = label; label = "file=" + label; //$NON-NLS-1$ } else { label = attributes.getValue(IAntModelConstants.ATTR_RESOURCE); if (label != null) { fReferencedName = label; label = "resource=" + label; //$NON-NLS-1$ } else { label = attributes.getValue(IAntModelConstants.ATTR_ENVIRONMENT); if (label != null) { label = "environment=" + label; //$NON-NLS-1$ } else { label = attributes.getValue("srcFile"); //$NON-NLS-1$ if (label != null) { fReferencedName = label; label = "srcFile=" + label; //$NON-NLS-1$ } } } } } else { fValue = attributes.getValue(IAntCoreConstants.VALUE); if (fValue == null) { fOccurrencesStartingPoint = IAntModelConstants.ATTR_LOCATION; fValue = attributes.getValue(fOccurrencesStartingPoint); } } setBaseLabel(label); } public String getProperty(String propertyName) { if (fProperties != null) { return fProperties.get(propertyName); } return null; } /* * (non-Javadoc) * * @see org.eclipse.ant.internal.ui.editor.model.AntElementNode#getBaseImageDescriptor() */ @Override protected ImageDescriptor getBaseImageDescriptor() { return AntUIImages.getImageDescriptor(IAntUIConstants.IMG_PROPERTY); } /** * Sets the properties in the project. */ @Override public boolean configure(boolean validateFully) { if (fConfigured) { return false; } try { getProjectNode().setCurrentConfiguringProperty(this); getTask().maybeConfigure(); getTask().execute(); fConfigured = true; } catch (BuildException be) { handleBuildException(be, AntEditorPreferenceConstants.PROBLEM_PROPERTIES); } catch (LinkageError le) { // A classpath problem with the property task. Known cause: // <property name= "hey" refId= "classFileSetId"/> where // classFileSetId refs a ClassFileSet which is an optional type that requires // BCEL JAR. Currently it is not possible to set these types of properties within the Ant Editor. // see bug 71888 handleBuildException(new BuildException(AntModelMessages.AntPropertyNode_0), AntEditorPreferenceConstants.PROBLEM_PROPERTIES); } catch (AntSecurityException se) { // either a system exit or setting of system property was attempted handleBuildException(new BuildException(AntModelMessages.AntPropertyNode_1), AntEditorPreferenceConstants.PROBLEM_SECURITY); } finally { getProjectNode().setCurrentConfiguringProperty(null); } return false; } /** * Adds this property name and value as being created by this property node declaration. * * @param propertyName * the name of the property * @param value * the value of the property */ public void addProperty(String propertyName, String value) { if (fProperties == null) { fProperties = new HashMap<>(1); } fProperties.put(propertyName, value); } /* * (non-Javadoc) * * @see org.eclipse.ant.internal.ui.model.AntElementNode#getReferencedElement(int) */ @Override public String getReferencedElement(int offset) { if (fReferencedName != null) { String textToSearch = getAntModel().getText(getOffset(), offset - getOffset()); if (textToSearch != null && textToSearch.length() != 0) { String attributeString = AntEditorCompletionProcessor.getAttributeStringFromDocumentStringToPrefix(textToSearch); if (IAntCoreConstants.FILE.equals(attributeString) || IAntModelConstants.ATTR_RESOURCE.equals(attributeString) || "srcFile".equals(attributeString)) { //$NON-NLS-1$ return fReferencedName; } } } return null; } /* * (non-Javadoc) * * @see org.eclipse.ant.internal.ui.model.AntElementNode#containsOccurrence(java.lang.String) */ @Override public boolean containsOccurrence(String identifier) { if (!getTask().getTaskName().equals("property")) { //$NON-NLS-1$ return super.containsOccurrence(identifier); } if (fValue != null) { return fValue.indexOf(identifier) != -1; } return false; } /* * (non-Javadoc) * * @see org.eclipse.ant.internal.ui.model.AntElementNode#getOccurrencesIdentifier() */ @Override public String getOccurrencesIdentifier() { if (fOccurrencesIdentifier == null) { fOccurrencesIdentifier = new StringBuffer("${").append(fBaseLabel).append('}').toString(); //$NON-NLS-1$ } return fOccurrencesIdentifier; } /* * (non-Javadoc) * * @see org.eclipse.ant.internal.ui.model.AntElementNode#isRegionPotentialReference(org.eclipse.jface.text.IRegion) */ @Override public boolean isRegionPotentialReference(IRegion region) { boolean superOK = super.isRegionPotentialReference(region); if (!getTask().getTaskName().equals("property") || !superOK) { //$NON-NLS-1$ return superOK; } String textToSearch = getAntModel().getText(getOffset(), getLength()); if (textToSearch == null) { return false; } int valueOffset = textToSearch.indexOf(fOccurrencesStartingPoint); if (valueOffset > -1) { valueOffset = textToSearch.indexOf('"', valueOffset); if (valueOffset > -1) { boolean inValue = region.getOffset() >= (getOffset() + valueOffset); if (inValue) { if ("{".equals(getAntModel().getText(region.getOffset() - 1, 1)) || "}".equals(getAntModel().getText(region.getOffset() + region.getLength(), 1))) { //$NON-NLS-1$ //$NON-NLS-2$ return true; } // reference is not in the value and not within a property de-reference return false; } return true; } } return false; } @Override public List<Integer> computeIdentifierOffsets(String identifier) { if (!getTask().getTaskName().equals("property")) { //$NON-NLS-1$ return super.computeIdentifierOffsets(identifier); } String textToSearch = getAntModel().getText(getOffset(), getLength()); if (textToSearch == null || textToSearch.length() == 0 || identifier.length() == 0) { return null; } List<Integer> results = new ArrayList<>(); if (fBaseLabel != null) { if (fBaseLabel.equals(identifier)) { int nameOffset = textToSearch.indexOf(IAntCoreConstants.NAME); nameOffset = textToSearch.indexOf(identifier, nameOffset + 1); results.add(new Integer(getOffset() + nameOffset)); } } if (fValue != null) { int valueOffset = textToSearch.indexOf(fOccurrencesStartingPoint); int endOffset = getOffset() + getLength(); while (valueOffset < endOffset) { valueOffset = textToSearch.indexOf(identifier, valueOffset); if (valueOffset == -1 || valueOffset > endOffset) { break; } results.add(new Integer(getOffset() + valueOffset)); valueOffset += identifier.length(); } } return results; } /* * (non-Javadoc) * * @see org.eclipse.ant.internal.ui.model.AntElementNode#isFromDeclaration(org.eclipse.jface.text.IRegion) */ @Override public boolean isFromDeclaration(IRegion region) { if (fBaseLabel == null) { return false; } if (fBaseLabel.length() != region.getLength()) { return false; } int offset = getOffset(); String textToSearch = getAntModel().getText(getOffset(), getLength()); if (textToSearch == null || textToSearch.length() == 0) { return false; } int nameStartOffset = textToSearch.indexOf(IAntCoreConstants.NAME); nameStartOffset = textToSearch.indexOf("\"", nameStartOffset); //$NON-NLS-1$ int nameEndOffset = textToSearch.indexOf("\"", nameStartOffset + 1); //$NON-NLS-1$ nameEndOffset += offset; nameStartOffset += offset; return nameStartOffset <= region.getOffset() && region.getOffset() + region.getLength() <= nameEndOffset; } }